package com.example.screenrecorder;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.core.content.ContextCompat;

import androidx.core.app.NotificationCompat;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 基础屏幕录制服务 - 提供标准的屏幕录制功能
 * 功能特性：
 * - 使用MediaProjection API进行屏幕捕获
 * - 支持音频录制（可配置开关）
 * - 多种视频质量设置
 * - 前台服务保证录制稳定性
 * - 悬浮窗控制器集成
 * - 自动文件命名和保存
 */
public class ScreenRecordService extends Service {
    
    private static final String TAG = "ScreenRecordService";
    public static final String ACTION_START_RECORDING = "start_recording";
    public static final String ACTION_STOP_RECORDING = "stop_recording";
    public static final String EXTRA_RESULT_CODE = "result_code";
    public static final String EXTRA_RESULT_DATA = "result_data";
    
    private static final String NOTIFICATION_CHANNEL_ID = "screen_recording_channel";
    private static final int NOTIFICATION_ID = 1001;
    
    private MediaProjection mediaProjection;
    private MediaRecorder mediaRecorder;
    private VirtualDisplay virtualDisplay;
    private MediaProjectionManager mediaProjectionManager;
    
    private static boolean isRecording = false;
    private String outputPath;
    
    @Override
    public void onCreate() {
        super.onCreate();
        mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        createNotificationChannel();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getAction();
            if (ACTION_START_RECORDING.equals(action)) {
                int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0);
                Intent resultData = intent.getParcelableExtra(EXTRA_RESULT_DATA);
                startRecording(resultCode, resultData);
            } else if (ACTION_STOP_RECORDING.equals(action)) {
                stopRecording();
            }
        }
        return START_STICKY;
    }
    
    private void startRecording(int resultCode, Intent resultData) {
        if (isRecording) {
            Log.w(TAG, "Recording already in progress");
            return;
        }
        
        try {
            Log.d(TAG, "Starting screen recording...");
            
            // 检查存储权限
            if (!checkStoragePermission()) {
                Log.e(TAG, "Storage permission not granted");
                Toast.makeText(this, "需要存储权限才能保存录制文件", Toast.LENGTH_LONG).show();
                stopSelf();
                return;
            }
            
            // 先启动前台服务，然后再创建MediaProjection
            startForegroundService();
            
            // 创建MediaProjection
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData);
            if (mediaProjection == null) {
                Log.e(TAG, "Failed to create MediaProjection");
                stopSelf();
                return;
            }
            
            // 注册MediaProjection回调（Android 14+ 要求）
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                mediaProjection.registerCallback(new MediaProjection.Callback() {
                    @Override
                    public void onStop() {
                        Log.d(TAG, "MediaProjection stopped");
                        stopRecording();
                    }
                }, null);
            }
            
            // 设置录制参数
            setupMediaRecorder();
            
            // 创建VirtualDisplay
            createVirtualDisplay();
            
            // 开始录制
            mediaRecorder.start();
            isRecording = true;
            
            // 显示前台通知
            startForeground(NOTIFICATION_ID, createNotification());
            
            // 启动悬浮窗控制器
            Intent floatingIntent = new Intent(this, FloatingController.class);
            startService(floatingIntent);
            
            Log.d(TAG, "Screen recording started successfully: " + outputPath);
            
        } catch (Exception e) {
            Log.e(TAG, "Error starting screen recording", e);
            // 清理资源
            cleanup();
            stopSelf();
        }
    }
    
    /**
     * 检查存储权限
     */
    private boolean checkStoragePermission() {
        Log.d(TAG, "Checking storage permission...");
        
        // 检查外部存储是否可用
        String state = Environment.getExternalStorageState();
        boolean isExternalStorageAvailable = Environment.MEDIA_MOUNTED.equals(state);
        Log.d(TAG, "External storage state: " + state + ", available: " + isExternalStorageAvailable);
        
        if (!isExternalStorageAvailable) {
            return false;
        }
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+ 使用新的媒体权限模型
            boolean hasVideoPermission = ContextCompat.checkSelfPermission(this, 
                android.Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED;
            boolean hasImagesPermission = ContextCompat.checkSelfPermission(this, 
                android.Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED;
            boolean hasWritePermission = ContextCompat.checkSelfPermission(this, 
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
            
            Log.d(TAG, "Android 13+ permissions - Video: " + hasVideoPermission + 
                  ", Images: " + hasImagesPermission + ", Write: " + hasWritePermission);
            
            // Android 13+ 只要有媒体权限就认为可以写入
            // 因为WRITE_EXTERNAL_STORAGE在Android 13+中可能不再有效
            return hasVideoPermission || hasImagesPermission || hasWritePermission;
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11-12 检查存储管理权限
            boolean hasManagerPermission = Environment.isExternalStorageManager();
            Log.d(TAG, "Android 11-12 storage manager permission: " + hasManagerPermission);
            
            // 如果没有管理权限，检查传统权限
            if (!hasManagerPermission) {
                boolean hasWritePermission = ContextCompat.checkSelfPermission(this, 
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
                Log.d(TAG, "Traditional write permission: " + hasWritePermission);
                return hasWritePermission;
            }
            return hasManagerPermission;
        } else {
            // Android 10 及以下使用传统存储权限
            boolean hasPermission = ContextCompat.checkSelfPermission(this, 
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
            Log.d(TAG, "Traditional storage permission: " + hasPermission);
            return hasPermission;
        }
    }
    
    /**
     * 启动前台服务
     */
    private void startForegroundService() {
        Log.d(TAG, "Starting foreground service...");
        
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setContentTitle("屏幕录制中")
                .setContentText("正在录制屏幕，点击停止录制")
                .setSmallIcon(android.R.drawable.ic_media_play)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setOngoing(true);
        
        // 添加停止录制的PendingIntent
        Intent stopIntent = new Intent(this, ScreenRecordService.class);
        stopIntent.setAction(ACTION_STOP_RECORDING);
        PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, 
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        
        builder.addAction(android.R.drawable.ic_media_pause, "停止录制", stopPendingIntent);
        
        Notification notification = builder.build();
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);
        } else {
            startForeground(NOTIFICATION_ID, notification);
        }
        
        Log.d(TAG, "Foreground service started");
    }
    
    /**
     * 清理资源
     */
    private void cleanup() {
        if (mediaRecorder != null) {
            try {
                mediaRecorder.release();
            } catch (Exception e) {
                Log.e(TAG, "Error releasing MediaRecorder", e);
            }
            mediaRecorder = null;
        }
        
        if (virtualDisplay != null) {
            virtualDisplay.release();
            virtualDisplay = null;
        }
        
        if (mediaProjection != null) {
            mediaProjection.stop();
            mediaProjection = null;
        }
        
        isRecording = false;
    }
    
    private void setupMediaRecorder() throws IOException {
        Log.d(TAG, "Setting up MediaRecorder...");
        
        mediaRecorder = new MediaRecorder();
        
        // 获取设置
        SharedPreferences prefs = getSharedPreferences("screen_recorder_settings", MODE_PRIVATE);
        boolean audioEnabled = SettingsActivity.isAudioEnabled(prefs);
        int videoQuality = SettingsActivity.getVideoQuality(prefs);
        
        Log.d(TAG, "Audio enabled: " + audioEnabled + ", Video quality: " + videoQuality);
        
        // 设置音频源（根据设置决定）
        if (audioEnabled) {
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            Log.d(TAG, "Audio source set to MIC");
        }
        
        // 设置视频源
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        Log.d(TAG, "Video source set to SURFACE");
        
        // 设置输出格式
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        Log.d(TAG, "Output format set to MPEG_4");
        
        // 设置编码器
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        if (audioEnabled) {
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            Log.d(TAG, "Audio encoder set to AAC");
        }
        Log.d(TAG, "Video encoder set to H264");
        
        // 设置视频参数
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        int density = metrics.densityDpi;
        
        Log.d(TAG, "Screen size: " + width + "x" + height + ", density: " + density);
        
        mediaRecorder.setVideoSize(width, height);
        mediaRecorder.setVideoFrameRate(30);
        
        // 根据设置调整视频质量
        int bitRate = getBitRateForQuality(videoQuality);
        mediaRecorder.setVideoEncodingBitRate(bitRate);
        Log.d(TAG, "Video bitrate set to: " + bitRate);
        
        // 设置音频参数
        if (audioEnabled) {
            mediaRecorder.setAudioSamplingRate(44100);
            mediaRecorder.setAudioEncodingBitRate(128000);
            mediaRecorder.setAudioChannels(2);
            Log.d(TAG, "Audio parameters set");
        }
        
        // 设置输出文件
        outputPath = createOutputPath();
        if (outputPath == null) {
            throw new IOException("Failed to create output path");
        }
        mediaRecorder.setOutputFile(outputPath);
        Log.d(TAG, "Output file set to: " + outputPath);
        
        // 准备录制器
        mediaRecorder.prepare();
        Log.d(TAG, "MediaRecorder prepared successfully");
    }
    
    private int getBitRateForQuality(int quality) {
        switch (quality) {
            case 0: return 2 * 1000 * 1000;  // 2 Mbps
            case 1: return 4 * 1000 * 1000;  // 4 Mbps
            case 2: return 8 * 1000 * 1000;  // 8 Mbps
            case 3: return 12 * 1000 * 1000; // 12 Mbps
            default: return 8 * 1000 * 1000; // 默认8 Mbps
        }
    }
    
    private void createVirtualDisplay() {
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        int density = metrics.densityDpi;
        
        virtualDisplay = mediaProjection.createVirtualDisplay(
                "ScreenRecord",
                width, height, density,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mediaRecorder.getSurface(),
                null, null
        );
    }
    
    private String createOutputPath() {
        try {
            // 使用外部存储的Movies目录
            File moviesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
            if (moviesDir == null) {
                Log.e(TAG, "Movies directory is null");
                return null;
            }
            
            // 创建ScreenRecord子目录
            File screenRecordDir = new File(moviesDir, "ScreenRecord");
            if (!screenRecordDir.exists()) {
                boolean created = screenRecordDir.mkdirs();
                if (!created) {
                    Log.e(TAG, "Failed to create ScreenRecord directory");
                    return null;
                }
                Log.d(TAG, "Created ScreenRecord directory: " + screenRecordDir.getAbsolutePath());
            }
            
            // 生成时间戳文件名
            String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            File outputFile = new File(screenRecordDir, "screen_record_" + timestamp + ".mp4");
            String outputPath = outputFile.getAbsolutePath();
            
            Log.d(TAG, "Output file path: " + outputPath);
            return outputPath;
            
        } catch (Exception e) {
            Log.e(TAG, "Error creating output path", e);
            return null;
        }
    }
    
    private void stopRecording() {
        if (!isRecording) {
            return;
        }
        
        try {
            if (mediaRecorder != null) {
                mediaRecorder.stop();
                mediaRecorder.release();
                mediaRecorder = null;
            }
            
            if (virtualDisplay != null) {
                virtualDisplay.release();
                virtualDisplay = null;
            }
            
            if (mediaProjection != null) {
                mediaProjection.stop();
                mediaProjection = null;
            }
            
            isRecording = false;
            
            // 停止前台服务
            stopForeground(true);
            stopSelf();
            
            Log.d(TAG, "Screen recording stopped. File saved: " + outputPath);
            
        } catch (Exception e) {
            Log.e(TAG, "Error stopping screen recording", e);
        }
    }
    
    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    NOTIFICATION_CHANNEL_ID,
                    "Screen Recording",
                    NotificationManager.IMPORTANCE_LOW
            );
            channel.setDescription("Screen recording notification");
            
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    
    private Notification createNotification() {
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );
        
        Intent stopIntent = new Intent(this, ScreenRecordService.class);
        stopIntent.setAction(ACTION_STOP_RECORDING);
        PendingIntent stopPendingIntent = PendingIntent.getService(
                this, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );
        
        return new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setContentTitle("屏幕录制中")
                .setContentText("点击停止录制")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentIntent(pendingIntent)
                .addAction(R.drawable.ic_launcher_foreground, "停止", stopPendingIntent)
                .setOngoing(true)
                .build();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        stopRecording();
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    public static boolean isRecording() {
        return isRecording;
    }
}
